有了冒險者之後,他們還需要各種裝備。假如一個冒險者需要武器、頭盔、上衣、褲子、鞋子5種裝備, 村莊內又有4種不同專業的冒險者,這樣我們就要建立20種工廠類別來生產裝備,而且每增加一種冒險者類別, 就要多增加5個實體工廠類別,如果使用剛才的工廠模式來管理生產裝備,實體工廠類別就會變非常得多,程式碼會很雜亂不易維護。 這時候工廠模式不能解決我們的問題,因此這邊改變一下工廠的定義,首先工廠仍然只是一個抽象介面(Factory),但是介面規定工廠現在生產的不是一種產品, 而是生產一個冒險者類別一系列所有的裝備,也就是說一間工廠要生產武器、頭盔、上衣、褲子、鞋子5種裝備(Product), 當然有了抽象工廠介面後當然也需要實體工廠(ConcreteFactory),例如說鬥士裝備生產工廠就會生產一系列的鬥士裝備(ConcreteProduct) ,這就是抽象工廠模式。 我們現在假設一個冒險者只有武器與上衣兩種裝備。
//上衣介面(Product)
abstract class Clothes {
var def: Int = 0 // 防禦力
//展示這件衣服
abstract fun displayMyClothes():String
}
//盔甲(ConcreteProduct)-鬥士上衣
class Armor : Clothes(){
override fun displayMyClothes() = "盔甲,防禦力${def}"
}
//皮衣(ConcreteProduct)-弓箭手上衣
class Leather : Clothes(){
override fun displayMyClothes() = "皮衣,防禦力${def}"
}
//武器介面(Product)
abstract class Weapon {
var atk: Int = 0 // 攻擊力
var range: Int = 0 // 攻擊範圍
//展示武器
abstract fun displayMyWeapon():String
}
//長劍(ConcreteProduct)-鬥士武器
class LongSword : Weapon(){
override fun displayMyWeapon() = "長劍,攻擊力${atk},範圍${range}"
}
//弓(ConcreteProduct)-弓箭手武器
class Bow : Weapon(){
override fun displayMyWeapon() = "弓箭,攻擊力${atk},範圍${range}"
}
//裝備工廠介面(Factory)-定義每一間工廠應該生產哪些東西
interface EquipFactory {
//製造武器
fun getWeapon(): Weapon
//製造衣服
fun getClothes(): Clothes
}
//生產鬥士裝備的工廠
object WarriorEquipFactory : EquipFactory {
override fun getWeapon(): Weapon {
val product = LongSword()
product.atk = 10
product.range = 1
return product
}
override fun getClothes(): Clothes {
val product = Armor()
product.def = 10
return product
}
}
//生產弓箭手裝備的工廠
object ArcherEquipFactory : EquipFactory {
override fun getWeapon(): Weapon {
val product = Bow()
product.atk = 10
product.range = 10
return product
}
override fun getClothes(): Clothes {
val product = Leather()
product.def = 5
return product
}
}
interface Adventurer {
val type: String
val weapon: Weapon //武器
val clothes: Clothes //衣服
fun introduceMySelf():String
}
// 弓箭手
class Archer : Adventurer {
override val type = "我是弓箭手"
override val clothes = ArcherEquipFactory.getClothes()
override val weapon = ArcherEquipFactory.getWeapon()
override fun introduceMySelf() = "${type}。${clothes.displayMyClothes()};${weapon.displayMyWeapon()}"
}
// 鬥士
class Warrior : Adventurer {
override val type = "我是鬥士"
override val clothes = WarriorEquipFactory.getClothes()
override val weapon = WarriorEquipFactory.getWeapon()
override fun introduceMySelf() = "${type}。${clothes.displayMyClothes()};${weapon.displayMyWeapon()}"
}
interface TrainingCamp{
fun trainAdventurer():Adventurer
}
object ArcherTrainingCamp:TrainingCamp {
override fun trainAdventurer(): Adventurer {
println("訓練一個弓箭手")
return Archer()
}
}
object WarriorTrainingCamp:TrainingCamp {
override fun trainAdventurer(): Adventurer{
println("訓練一個鬥士")
return Warrior()
}
}
val archer = ArcherTrainingCamp.trainAdventurer()
println(archer.introduceMySelf())
val warrior = WarriorTrainingCamp.trainAdventurer()
println(warrior.introduceMySelf())
訓練一個弓箭手
我是弓箭手。皮衣,防禦力5;弓箭,攻擊力10,範圍10
訓練一個鬥士
我是鬥士。盔甲,防禦力10;長劍,攻擊力10,範圍1
工廠模式最大的好處就是,三種模式皆符合單一職責原則,分工明確,而使用者使用產品時不需理解產品是如何產生的。
更加封閉了應該封閉的地方,也更加放寬了應該開放讓使用者自定義的地方,也更加分離了各自類別必須獨立負責的事。